/**
 * $RCSfile: DateUtil.java,v $
 * $Revision: 1.3 $
 * $Date: 2006/09/29 02:51:11 $
 *
 * Copyright (C) 2005 ICSS, Inc. All rights reserved.
 *
 * This software is the proprietary information of ICSS, Inc.
 * Use is subject to license terms.
 */
package com.person.commons.utils;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import sun.awt.AppContext;


/**
 * <p>
 * Title: 办公自动化
 * </p>
 * <p>
 * Description: 日期时间处理应用类
 * </p>
 * <p>
 * Copyright: Copyright (c) 2008
 * </p>
 * <p>
 * Company: 德盛世纪设计院（decentsoft）
 * </p>
 * 
 * @author Wang Zitao
 * @version 1.0
 */
public class DateUtil {

	/** 年月日模式字符串 */
	public static final String YEAR_MONTH_DAY_PATTERN = "yyyy-MM-dd";

	/** 时分秒模式字符串 */
	public static final String HOUR_MINUTE_SECOND_PATTERN = "HH:mm:ss";

	/** 年月日时分秒模式字符串 */
	public static final String YMDHMS_PATTERN = "yyyy-MM-dd HH:mm:ss";
	/**
	 * 从数据库服务器获取当前时间。
	 * 
	 * @return 返回当前时间
	 * @throws SQLException
	 *             获取数据库时间时发生错误
	 */
	public static Date currentDate() {
//	Date result = null;
//
//	PreparedStatement pst = null;
//	ResultSet rs = null;
//	Session session = null;
//	try {
//		SessionFactory sf = (SessionFactory) new Configuration().configure().buildSessionFactory(); 
//		session = sf.openSession();
//		Connection conn = session.connection();
//		pst = conn.prepareStatement("select now()");
//		rs = pst.executeQuery();
//		if (rs.next()) {
//			Timestamp ts = rs.getTimestamp(1);
//			if (ts != null) {
//				result = new Date(ts.getTime());
//			}
//		}
//	} catch (SQLException ex) {
//		result = new Date();
//	} finally {
//		if (rs != null) {
//			try {
//				rs.close();
//				rs = null;
//			} catch (SQLException sqle) {
//				// ignore it
//			}
//		}
//		if (pst != null) {
//			try {
//				pst.close();
//				pst = null;
//			} catch (SQLException sqle) {// ignore it}
//			}
//		}
//		if (session != null) {
//			session.close();
//		}
//	}

	return new Date();
}

/**
 * 从数据库服务器获取当前时间并根据传入的patter转换成字符串形式。
 * 
 * @param pattern
 *            日期pattern
 * @return 返回当前时间根据传入pattern转换后的字符串
 * @throws SQLException
 *             获取数据库时间时发生错误
 */
public static String currentDateString(final String pattern){
	return format(currentDate(), pattern);
}

/**
 * 从数据库服务器获取当前时间并转换成默认字符串形式（yyyy-MM-dd）。
 * 
 * @return 返回当前时间的默认字符串形式（yyyy-MM-dd）
 * @throws SQLException
 *             获取数据库时间时发生错误
 */
public static String currentDateDefaultString() throws SQLException {
	return format(currentDate(), YEAR_MONTH_DAY_PATTERN);
}

	/**
	 * 获取给定日期对象的年
	 * 
	 * @param date
	 *            日期对象
	 * @return 年
	 */
	public static int getYear(final Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.YEAR);
	}

	/**
	 * 获取给定日期对象的月
	 * 
	 * @param date
	 *            日期对象
	 * @return 月
	 */
	public static int getMonth(final Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.MONTH) + 1;
	}

	/**
	 * 获取给定日期对象的天
	 * 
	 * @param date
	 *            日期对象
	 * @return 天
	 */
	public static int getDay(final Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.DATE);
	}

	/**
	 * 获取给定日期对象的时
	 * 
	 * @param date
	 *            日期对象
	 * @return 时
	 */
	public static int getHour(final Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.HOUR);
	}

	/**
	 * 获取给定日期对象的分
	 * 
	 * @param date
	 *            日期对象
	 * @return 分
	 */
	public static int getMinute(final Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.MINUTE);
	}

	/**
	 * 获取给定日期对象的秒
	 * 
	 * @param date
	 *            日期对象
	 * @return 秒
	 */
	public static int getSecond(final Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.SECOND);
	}

	/**
	 * 获取传入日期的年和月的Integer形式（yyyyMM）。
	 * 
	 * @param date
	 *            要转换的日期对象
	 * @return 转换后的Integer对象
	 */
	public static Integer getYearMonth(final Date date) {
		return new Integer(format(date, "yyyyMM"));
	}

	/**
	 * 将年月的整数形式（yyyyMM）转换为日期对象返回。
	 * 
	 * @param yearMonth
	 *            年月的整数形式（yyyyMM）
	 * @return 日期类型
	 * @throws ParseException
	 */
	public static Date parseYearMonth(final Integer yearMonth)
			throws ParseException {
		return parse(String.valueOf(yearMonth), "yyyyMM");
	}

	/**
	 * 将某个日期增加指定年数，并返回结果。如果传入负数，则为减。
	 * 
	 * @param date
	 *            要操作的日期对象
	 * @param ammount
	 *            要增加年的数目
	 * @return 结果日期对象
	 */
	public static Date addYear(final Date date, final int ammount) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.YEAR, ammount);
		return c.getTime();
	}

	/**
	 * 将某个日期增加指定月数，并返回结果。如果传入负数，则为减。
	 * 
	 * @param date
	 *            要操作的日期对象
	 * @param ammount
	 *            要增加月的数目
	 * @return 结果日期对象
	 */
	public static Date addMonth(final Date date, final int ammount) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.MONTH, ammount);
		return c.getTime();
	}

	/**
	 * 将某个日期增加指定天数，并返回结果。如果传入负数，则为减。
	 * 
	 * @param date
	 *            要操作的日期对象
	 * @param ammount
	 *            要增加天的数目
	 * @return 结果日期对象
	 */
	public static Date addDay(final Date date, final int ammount) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.DATE, ammount);
		return c.getTime();
	}

	/**
	 * 将给定整数形式的年月增加指定月数，并返回结果。如果传入负数，则为减。
	 * 
	 * @param yearMonth
	 *            要操作的年月
	 * @param ammount
	 *            要增加的月数
	 * @return 结果年月
	 * @throws ParseException
	 */
	public static Integer addMonth(final Integer yearMonth, final int ammount)
			throws ParseException {
		return getYearMonth(addMonth(parseYearMonth(yearMonth), ammount));
	}

	/**
	 * 返回给定的beforeDate比afterDate早的年数。如果beforeDate晚于afterDate，则 返回负数。
	 * 
	 * @param beforeDate
	 *            要比较的早的日期
	 * @param afterDate
	 *            要比较的晚的日期
	 * @return beforeDate比afterDate早的年数，负数表示晚。
	 */
	public static int beforeYears(final Date beforeDate, final Date afterDate) {
		Calendar beforeCalendar = Calendar.getInstance();
		beforeCalendar.setTime(beforeDate);
		beforeCalendar.set(Calendar.MONTH, 1);
		beforeCalendar.set(Calendar.DATE, 1);
		beforeCalendar.set(Calendar.HOUR, 0);
		beforeCalendar.set(Calendar.SECOND, 0);
		beforeCalendar.set(Calendar.MINUTE, 0);
		Calendar afterCalendar = Calendar.getInstance();
		afterCalendar.setTime(afterDate);
		afterCalendar.set(Calendar.MONTH, 1);
		afterCalendar.set(Calendar.DATE, 1);
		afterCalendar.set(Calendar.HOUR, 0);
		afterCalendar.set(Calendar.SECOND, 0);
		afterCalendar.set(Calendar.MINUTE, 0);
		boolean positive = true;
		if (beforeDate.after(afterDate))
			positive = false;
		int beforeYears = 0;
		while (true) {
			boolean yearEqual = beforeCalendar.get(Calendar.YEAR) == afterCalendar
					.get(Calendar.YEAR);
			if (yearEqual) {
				break;
			} else {
				if (positive) {
					beforeYears++;
					beforeCalendar.add(Calendar.YEAR, 1);
				} else {
					beforeYears--;
					beforeCalendar.add(Calendar.YEAR, -1);
				}
			}
		}
		return beforeYears;
	}

	/**
	 * 返回给定的beforeDate比afterDate早的月数。如果beforeDate晚于afterDate，则 返回负数。
	 * 
	 * @param beforeDate
	 *            要比较的早的日期
	 * @param afterDate
	 *            要比较的晚的日期
	 * @return beforeDate比afterDate早的月数，负数表示晚。
	 */
	public static int beforeMonths(final Date beforeDate, final Date afterDate) {
		Calendar beforeCalendar = Calendar.getInstance();
		beforeCalendar.setTime(beforeDate);
		beforeCalendar.set(Calendar.DATE, 1);
		beforeCalendar.set(Calendar.HOUR, 0);
		beforeCalendar.set(Calendar.SECOND, 0);
		beforeCalendar.set(Calendar.MINUTE, 0);
		Calendar afterCalendar = Calendar.getInstance();
		afterCalendar.setTime(afterDate);
		afterCalendar.set(Calendar.DATE, 1);
		afterCalendar.set(Calendar.HOUR, 0);
		afterCalendar.set(Calendar.SECOND, 0);
		afterCalendar.set(Calendar.MINUTE, 0);
		boolean positive = true;
		if (beforeDate.after(afterDate))
			positive = false;
		int beforeMonths = 0;
		while (true) {
			boolean yearEqual = beforeCalendar.get(Calendar.YEAR) == afterCalendar
					.get(Calendar.YEAR);
			boolean monthEqual = beforeCalendar.get(Calendar.MONTH) == afterCalendar
					.get(Calendar.MONTH);
			if (yearEqual && monthEqual) {
				break;
			} else {
				if (positive) {
					beforeMonths++;
					beforeCalendar.add(Calendar.MONTH, 1);
				} else {
					beforeMonths--;
					beforeCalendar.add(Calendar.MONTH, -1);
				}
			}
		}
		return beforeMonths;
	}

	/**
	 * 返回给定的beforeDate比afterDate早的天数。如果beforeDate晚于afterDate，则 返回负数。
	 * 
	 * @param beforeDate
	 *            要比较的早的日期
	 * @param afterDate
	 *            要比较的晚的日期
	 * @return beforeDate比afterDate早的天数，负数表示晚。
	 */
	public static int beforeDays(final Date beforeDate, final Date afterDate) {
		Calendar beforeCalendar = Calendar.getInstance();
		beforeCalendar.setTime(beforeDate);
		beforeCalendar.set(Calendar.HOUR, 0);
		beforeCalendar.set(Calendar.SECOND, 0);
		beforeCalendar.set(Calendar.MINUTE, 0);
		Calendar afterCalendar = Calendar.getInstance();
		afterCalendar.setTime(afterDate);
		afterCalendar.set(Calendar.HOUR, 0);
		afterCalendar.set(Calendar.SECOND, 0);
		afterCalendar.set(Calendar.MINUTE, 0);
		boolean positive = true;
		if (beforeDate.after(afterDate))
			positive = false;
		int beforeDays = 0;
		while (true) {
			boolean yearEqual = beforeCalendar.get(Calendar.YEAR) == afterCalendar
					.get(Calendar.YEAR);
			boolean monthEqual = beforeCalendar.get(Calendar.MONTH) == afterCalendar
					.get(Calendar.MONTH);
			boolean dayEqual = beforeCalendar.get(Calendar.DATE) == afterCalendar
					.get(Calendar.DATE);
			if (yearEqual && monthEqual && dayEqual) {
				break;
			} else {
				if (positive) {
					beforeDays++;
					beforeCalendar.add(Calendar.DATE, 1);
				} else {
					beforeDays--;
					beforeCalendar.add(Calendar.DATE, -1);
				}
			}
		}
		return beforeDays;
	}

	/**
	 * 获取beforeDate和afterDate之间相差的完整年数，精确到天。负数表示晚。
	 * 
	 * @param beforeDate
	 *            要比较的早的日期
	 * @param afterDate
	 *            要比较的晚的日期
	 * @return beforeDate比afterDate早的完整年数，负数表示晚。
	 */
	public static int beforeRoundYears(final Date beforeDate,
			final Date afterDate) {
		Date bDate = beforeDate;
		Date aDate = afterDate;
		boolean positive = true;
		if (beforeDate.after(afterDate)) {
			positive = false;
			bDate = afterDate;
			aDate = beforeDate;
		}
		int beforeYears = beforeYears(bDate, aDate);

		int bMonth = getMonth(bDate);
		int aMonth = getMonth(aDate);
		if (aMonth < bMonth) {
			beforeYears--;
		} else if (aMonth == bMonth) {
			int bDay = getDay(bDate);
			int aDay = getDay(aDate);
			if (aDay < bDay) {
				beforeYears--;
			}
		}

		if (positive) {
			return beforeYears;
		} else {
			return new BigDecimal(beforeYears).negate().intValue();
		}
	}

	/**
	 * 获取beforeDate和afterDate之间相差的完整年数，精确到月。负数表示晚。
	 * 
	 * @param beforeDate
	 *            要比较的早的日期
	 * @param afterDate
	 *            要比较的晚的日期
	 * @return beforeDate比afterDate早的完整年数，负数表示晚。
	 */
	public static int beforeRoundAges(final Date beforeDate,
			final Date afterDate) {
		Date bDate = beforeDate;
		Date aDate = afterDate;
		boolean positive = true;
		if (beforeDate.after(afterDate)) {
			positive = false;
			bDate = afterDate;
			aDate = beforeDate;
		}
		int beforeYears = beforeYears(bDate, aDate);

		int bMonth = getMonth(bDate);
		int aMonth = getMonth(aDate);
		if (aMonth < bMonth) {
			beforeYears--;
		}

		if (positive) {
			return beforeYears;
		} else {
			return new BigDecimal(beforeYears).negate().intValue();
		}
	}

	/**
	 * 获取beforeDate和afterDate之间相差的完整月数，精确到天。负数表示晚。
	 * 
	 * @param beforeDate
	 *            要比较的早的日期
	 * @param afterDate
	 *            要比较的晚的日期
	 * @return beforeDate比afterDate早的完整月数，负数表示晚。
	 */
	public static int beforeRoundMonths(final Date beforeDate,
			final Date afterDate) {
		Date bDate = beforeDate;
		Date aDate = afterDate;
		boolean positive = true;
		if (beforeDate.after(afterDate)) {
			positive = false;
			bDate = afterDate;
			aDate = beforeDate;
		}
		int beforeMonths = beforeMonths(bDate, aDate);

		int bDay = getDay(bDate);
		int aDay = getDay(aDate);
		if (aDay < bDay) {
			beforeMonths--;
		}

		if (positive) {
			return beforeMonths;
		} else {
			return new BigDecimal(beforeMonths).negate().intValue();
		}
	}

	/**
	 * 根据传入的年、月、日构造日期对象
	 * 
	 * @param year
	 *            年
	 * @param month
	 *            月
	 * @param date
	 *            日
	 * @return 返回根据传入的年、月、日构造的日期对象
	 */
	public static Date getDate(final int year, final int month, final int date) {
		Calendar c = Calendar.getInstance();
		c.set(year + 1900, month, date);
		return c.getTime();
	}

	/**
	 * 根据传入的日期格式化pattern将传入的日期格式化成字符串。
	 * 
	 * @param date
	 *            要格式化的日期对象
	 * @param pattern
	 *            日期格式化pattern
	 * @return 格式化后的日期字符串
	 */
	public static String format(final Date date, final String pattern) {
		DateFormat df = new SimpleDateFormat(pattern);
		return df.format(date);
	}

	/**
	 * 将传入的日期按照默认形势转换成字符串（yyyy-MM-dd）
	 * 
	 * @param date
	 *            要格式化的日期对象
	 * @return 格式化后的日期字符串
	 */
	public static String format(final Date date) {
		return format(date, YEAR_MONTH_DAY_PATTERN);
	}

	/**
	 * 根据传入的日期格式化patter将传入的字符串转换成日期对象
	 * 
	 * @param dateStr
	 *            要转换的字符串
	 * @param pattern
	 *            日期格式化pattern
	 * @return 转换后的日期对象
	 * @throws ParseException
	 *             如果传入的字符串格式不合法
	 */
	public static Date parse(final String dateStr, final String pattern)
			throws ParseException {
		DateFormat df = new SimpleDateFormat(pattern);
		return df.parse(dateStr);
	}

	/**
	 * 将传入的字符串按照默认格式转换为日期对象（yyyy-MM-dd）
	 * 
	 * @param dateStr
	 *            要转换的字符串
	 * @return 转换后的日期对象
	 * @throws ParseException
	 *             如果传入的字符串格式不符合默认格式（如果传入的字符串格式不合法）
	 */
	public static Date parse(final String dateStr) throws ParseException {
		return parse(dateStr, YEAR_MONTH_DAY_PATTERN);
	}

	/**
	 * 要进行合法性验证的年月数值
	 * 
	 * @param yearMonth
	 *            验证年月数值
	 * @return 年月是否合法
	 */
	public static boolean isYearMonth(final Integer yearMonth) {
		String yearMonthStr = yearMonth.toString();
		return isYearMonth(yearMonthStr);
	}

	/**
	 * 要进行合法性验证的年月字符串
	 * 
	 * @param yearMonthStr
	 *            验证年月字符串
	 * @return 年月是否合法
	 */
	public static boolean isYearMonth(final String yearMonthStr) {
		if (yearMonthStr.length() != 6)
			return false;
		else {
			String yearStr = yearMonthStr.substring(0, 4);
			String monthStr = yearMonthStr.substring(4, 6);
			try {
				int year = Integer.parseInt(yearStr);
				int month = Integer.parseInt(monthStr);
				if (year < 1800 || year > 3000) {
					return false;
				}
				if (month < 1 || month > 12) {
					return false;
				}
				return true;
			} catch (Exception e) {
				return false;
			}
		}
	}

	/**
	 * 获取从from到to的年月Integer形式值的列表
	 * 
	 * @param from
	 *            从
	 * @param to
	 *            到
	 * @return 年月Integer形式值列表
	 * @throws ParseException
	 */
	public static List getYearMonths(Integer from, Integer to)
			throws ParseException {
		List yearMonths = new ArrayList();
		Date fromDate = parseYearMonth(from);
		Date toDate = parseYearMonth(to);
		
		//ranxk 
		if(from.equals(to)){
			yearMonths.add(from);
			return yearMonths;
		}
		
		if (fromDate.after(toDate))
			throw new IllegalArgumentException(
					"'from' date should before 'to' date!");
		Date tempDate = fromDate;
		while (tempDate.before(toDate)) {
			yearMonths.add(getYearMonth(tempDate));
			tempDate = addMonth(tempDate, 1);
		}
		if (!from.equals(to)) {
			yearMonths.add(to);
		}

		return yearMonths;
	}
	
	
	/**
	 * 根据传入的日期对象获得中文日期
	 * @param date
	 * @return Sring  与传入日期相对应的中文日期对象
	 */
	
	
	public   static   String   chineseDate(Date date){
		  StringBuffer chineseDate=new StringBuffer();
		  String month=String.valueOf(getMonth(date));
		  String day=String.valueOf(getDay(date));
		  String year=String.valueOf(getYear(date));
		  
		  
		  //将年份转化成中文
		  chineseDate.append(getChinese(Integer.parseInt(year.substring(0,1))));
		  chineseDate.append(getChinese(Integer.parseInt(year.substring(1,2))));
		  chineseDate.append(getChinese(Integer.parseInt(year.substring(2,3))));
		  chineseDate.append(getChinese(Integer.parseInt(year.substring(3,4))));
		  chineseDate.append("年");
          //将月份转化为中文 
		  if(month.length()<2)
		  {
			  if("9".equals(month)){
				  chineseDate.append("十");
				  }
			  else{
				  chineseDate.append(getChinese(Integer.parseInt(month)+1));
			  }
		  }else{
			  chineseDate.append("十");
			  chineseDate.append(getChinese(Integer.parseInt(year.substring(1,2))+1));
		  }
		  chineseDate.append("月"); 
		  
		  //将日期转化为中文 
		  if(day.length()<2)
		  {
			  chineseDate.append(getChinese(Integer.parseInt(day)));
		  }else{
			  if("1".equals(day.substring(0,1))){
				  chineseDate.append("十");
				  if(!"0".equals(day.substring(1,2)))
					  chineseDate.append(getChinese(Integer.parseInt(day.substring(1,2))));
			  }else{
				  chineseDate.append(getChinese(Integer.parseInt(day.substring(0,1))));
				  chineseDate.append("十");
				  if(!"0".equals(day.substring(1,2)))
					  chineseDate.append(getChinese(Integer.parseInt(day.substring(1,2))));
			  }
		  }
		chineseDate.append("日"); 
		return   chineseDate.toString();   
		  }   
		    
		  private   static   String   getChinese(int   digital){   
		  switch(digital){   
		  case   0:   
		  return   "零";   
		  case   1:   
		  return   "一";   
		  case   2:   
		  return   "二";   
		  case   3:   
		  return   "三";   
		  case   4:   
		  return   "四";   
		  case   5:   
		  return   "五";   
		  case   6:   
		  return   "六";   
		  case   7:   
		  return   "七";   
		  case   8:   
		  return   "八";   
		  case   9:   
		  return   "九";	   
		  }   
		  return   "零";	   
		  }   
}